package com.zang.blogz.strategy.impl;


import com.zang.blogz.constant.ResultConstant;
import com.zang.blogz.exception.BizException;

import com.zang.blogz.strategy.UploadStrategy;
import com.zang.blogz.utils.FileUtils;
import io.github.vampireachao.stream.core.optional.Opp;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * @Author: ZVerify
 * @Description:  抽象上传模板
 * @DateTime: 2022/8/31 18:55
 **/
public abstract class AbstractUploadStrategyImpl implements UploadStrategy {


    @Override
    public String uploadFile(MultipartFile file, String path) {

        Opp<String> uploadOpp = Opp.ofTry(() -> {
            // 获取文件md5值
            String md5 = FileUtils.getMd5(file.getInputStream());
            // 获取文件扩展名
            String extName = FileUtils.getExtName(file.getOriginalFilename());
            // 重新生成文件名
            String fileName = md5 + extName;
            // 判断文件是否已存在
            if (!exists(path + fileName)) {
                // 不存在则继续上传
                upload(path, fileName, file.getInputStream());
            }
            // 返回文件访问路径
            return getFileAccessUrl(path + fileName);
        });

        if (Opp.of(uploadOpp.getException()).isPresent()) {

            throw new BizException(ResultConstant.FileMessage.FILE_EXCEPTION);
        }

        return uploadOpp.get();
    }

    @Override
    public String uploadFile(String fileName, ByteArrayInputStream inputStream, String path) {

        Opp<String> urlOpp = Opp.ofTry(() -> {

            upload(path, fileName, inputStream);

            return getFileAccessUrl(path + fileName);
        });
        if (urlOpp.getException() != null){

            throw new BizException(ResultConstant.FileMessage.FILE_EXCEPTION);
        }

        return urlOpp.get();
    }

    /**
     * 判断文件是否存在
     *
     * @param filePath 文件路径
     * @return {@link Boolean}
     */
    public abstract Boolean exists(String filePath);

    /**
     * 上传
     *
     * @param path        路径
     * @param fileName    文件名
     * @param inputStream 输入流
     * @throws IOException io异常
     */
    public abstract void upload(String path, String fileName, InputStream inputStream) throws IOException;

    /**
     * 获取文件访问url
     *
     * @param filePath 文件路径
     * @return {@link String}
     */
    public abstract String getFileAccessUrl(String filePath);
}
